package com.jlf.core.error;

import java.lang.reflect.Field;

/**
 * 错误码常量定义
 *
 * @author wujr
 * 2022/2/24
 * @version 1.0
 * 变更历史
 * [wujr 2022/2/24 1.0 新增]
 */
public interface Errors {
    Code UNKNOWN = new Code(-1, "unknown");
    Code SUCCEED = new Code(0, "succeed");

    Code OBJECT_STATUS_MISMATCH = new Code(10, "对象状态不一致");
    Code NO_OBJECT = new Code(11, "对象不存在");
    Code OBJECT_ALREADY_EXIST = new Code(12, "对象已经存在");
    Code OBJECT_SAVE = new Code(13, "保存对象失败");
    Code OBJECT_UPDATE = new Code(14, "更新对象失败");
    Code OBJECT_DELETE = new Code(15, "删除对象失败");
    Code OBJECT_VERSION_MISMATCH = new Code(16, "对象版本不一致");
    Code NULL_REFERENCE = new Code(17, "引用对象不存在");
    Code REFERENCE_MISMATCH = new Code(18, "引用对象不匹配");
    Code OBJECT_REFERENCED = new Code(19, "对象已经被引用");
    Code OBJECT_NOT_BELONG_TO = new Code(20, "对象不属于自己");
    Code OBJECT_RESERVED = new Code(21, "为保留对象");
    Code OBJECT_HAS_PROPERTY = new Code(22, "对象已经有属性");
    Code OBJECT_NO_PROPERTY = new Code(23, "对象没有属性");
    Code OBJECT_TYPE_CONVERT_UNSUPPORTED = new Code(24, "不支持的对象类转换");


    // 配置管理的错误
    Code SCM_PARAMETER_NOT_EXIST = new Code(30, "参数未配置");
    Code CONFIGURATION_MISSING = new Code(21, "缺少配置");
    Code SCM_DOMAIN_NOT_FOUND = new Code(22, "没有找到领域配置");
    Code SMS_CODE_NOT_FOUND = new Code(23, "没有找到短信验证码");
    Code SMS_CODE_MISMATCH = new Code(24, "短信验证码不匹配");

    Code ACM_CERT_CHARACTER_INVALID = new Code(50, "无效的证书特征");
    Code ACM_CERT_CHARACTER_MISMATCH = new Code(51, "证书特征不匹配");
    Code ACM_ISSUER_UNSUPPORTED = new Code(52, "不支持的发行商");
    Code ACM_CA_ISSUED = new Code(53, "证书已经签发");
    Code ACM_CERTIFICATE_INVALID = new Code(54, "无效的证书内容");
    Code ACM_COMPONENT_NOT_EXIST = new Code(55, "组件不存在");

    Code ACM_AUTHENTICATE_REJECTED = new Code(400, "认证拒绝");
    Code ACM_UNAUTHORIZED = new Code(401, "没有授权");
    Code ACM_CA_INVALID = new Code(402, "无效的证书");
    Code ACM_CA_NOT_ISSUE = new Code(403, "根证书未颁发");
    Code ACM_API_UNSUPPORTED = new Code(404, "不支持的接口");
    // 405：Method Not Allowed请求行中指定的方法不能用于请求相应的资源
    Code ACM_ALGORITHM_UNSUPPORTED = new Code(405, "不支持的认证算法");
    // 406 Not Acceptable请求的资源的内容特性无法满足请求头中的条件，因而无法生成响应实体
    Code ACM_ALGORITHM_FORMAT = new Code(406, "认证算法格式不正确");
    // 407 Proxy Authentication Required与401响应类似，只不过客户端必须在代理服务器上进行身份验证
    Code ACM_PASSWORD_MISMATCH = new Code(407,"用户密码不正确");
    Code ACM_AUTHENTICATE_SIGNATURE = new Code(408, "计算认证签名错误");
    Code ACM_FLOW_LIMIT = new Code(409, "限流");
    // 410 Gone被请求的资源在服务器上已经不再可用，而且没有任何已知的转发地址。
    Code ACM_LOGOFF_ALREADY = new Code(410, "用户已经退出登录");
    // 411 Length Required服务器拒绝在没有定义Content-Length头的情况下接受请求。
    Code ACM_ALGORITHM_RANDOM = new Code(411, "认证随机数不在范围内");
    // 412 Precondition Failed服务器在验证在请求的头字段中给出先决条件时，没能满足其中的一个或多个。
    Code ACM_ALGORITHM_LENGTH = new Code(412, "认证签名计算长度不正确");
    // 413 Request Entity Too Large服务器拒绝处理当前请求，因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围。
    Code ACM_NOT_LOGIN = new Code(413, "用户未登录");
    // 415 Unsupported Media Type对于当前请求的方法和所请求的资源，请求中提交的实体并不是服务器中所支持的格式，因此请求被拒绝。
    Code ACM_TOKEN_INVALID = new Code(415, "无效认证令牌");
    // 416 Requested Range Not Satisfiable如果请求中包含了Range请求头，并且Range中指定的任何数据范围都与当前资源的可用范围不重合，同时请求中又没有定义If-Range请求头，那么服务器就应当返回416状态码。
// 416 Requested Range Not Satisfiable如果请求中包含了Range请求头，并且Range中指定的任何数据范围都与当前资源的可用范围不重合，同时请求中又没有定义If-Range请求头，那么服务器就应当返回416状态码。
    Code ACM_APP_UNSUPPORTED = new Code(416, "不支持的接入应用");
    // 417 Expectation Failed在请求头Expect中指定的预期内容无法被服务器满足，或者这个服务器是一个代理服务器，它有明显的证据证明在当前路由的下一个节点上，Expect的内容无法被满足。
    Code API_PARAMETER = new Code(417, "接口参数错误");
    Code API_FILE_EMPTY = new Code(418, "上传附件，附件内容为空");
    Code API_FILE_STREAM = new Code(419, "上传附件，无法读取附件");
    Code API_EXT_UNSUPPORTED = new Code(420, "不支持的附件文件类型");
    /**
     * 分片上传未申请
     */
    Code API_FILE_CHUNK_REQUEST = new Code(421, "分片上传请求未申请");
    // 422 Unprocessable Entity请求格式正确，但是由于含有语义错误，无法响应。
    Code API_FILE_FORMAT = new Code(422, "上传附件，附件格式错误");
    Code API_FILE_STORAGE = new Code(423, "对象存储失败");
    Code API_FILE_CHUNK_UPLOAD = new Code(424, "对象分片上传失败");
    Code API_FILE_CHUNK_MERGE = new Code(425, "对象分片合并失败");
    Code ACM_AUTHENTICATION_MISSING = new Code(428, "缺少认证参数");

    // 权限管理错误
    Code ACM_USER_UNREGISTERED = new Code(430, "账户未注册");
    Code ACM_USER_DELETE_SYSTEM = new Code(431, "系统用户不能被删除");
    Code ACM_USER_DELETE_SELF = new Code(432, "用户无法删除自身");
    Code ACM_ROLE_DELETE_SYSTEM = new Code(433,"系统角色不能被删除");
    Code ACM_APPLICATION_DEL_SELF = new Code(434, "不能删除自身应用");
    Code ACM_LICENSE_NOT_EXISTS = new Code(435, "凭证不存在");
    Code ACM_USER_NOT_GRANT_APPLICATION = new Code(436, "用户没有授权给应用");
    Code ACM_API_NOT_GRANT_APPLICATION = new Code(437, "接口没有授权给应用");
    Code ACM_APPLICATION_NOT_OP = new Code(438, "非运营类应用");
    Code ACM_APPLICATION_THIRD = new Code(439, "第三方应用");
    Code ACM_TENANT_NOT_EXIST = new Code(440, "租户不存在");
    Code ACM_CUSTOMER_UNREGISTERED = new Code(441, "客户未注册");
    Code ACM_USER_GRANT_SELF = new Code(442, "用户不能进行自我授权");
    Code ACM_LICENSE_EFFECTIVE = new Code(443, "凭证已经生效");
    Code ACM_APPLICATION_CENTRAL = new Code(444, "中心应用");
    Code ACM_APPLICATION_BUSINESS = new Code(445, "业务应用");
    Code ACM_CUSTOMER_MISMATCH = new Code(446, "客户不匹配");
    Code ACM_TENANT_FORMAL = new Code(447, "正式租户");
    Code ACM_TENANT_UNREGISTERED = new Code(448, "租户未注册");
    Code ACM_TENANT_MISMATCH = new Code(449, "租户不匹配");
    Code ACM_ROLE_NOT_EXISTS = new Code(450, "角色不存在");
    Code ACM_PERMISSION_NOT_EXISTS = new Code(451, "权限不存在");
    Code ACM_APPLICATION_MISMATCH = new Code(452, "应用不匹配");
    Code ACM_CUSTOMER_CA_ROOT_NOT_BUILD = new Code(453, "客户尚未颁发根证书");
    Code ACM_TENANT_CA_ROOT_NOT_BUILD = new Code(454, "租户尚未颁发根证书");
    Code ACM_LICENSE_ISSUER_ERROR = new Code(455, "颁发证书失败");
    Code ACM_CA_SUBJECT_MISMATCH = new Code(456, "证书的主体不匹配");
    Code ACM_CA_SERIAL_MISMATCH = new Code(457, "证书的序号不匹配");
    Code ACM_AC_HARDWARE_MISMATCH = new Code(458, "证书的硬件特征不一致");
    Code ACM_CUSTOMER_LACK_OF_TENANT = new Code(459, "客户租户资料缺失");
    Code ACM_CA_RUN_MODE_MISMATCH = new Code(460, "证书的运行模式不一致");
    Code ACM_CA_SERVICE_ERROR = new Code(461, "许可服务错误");
    Code ACM_CA_NO_VALID_LICENSE = new Code(462, "没有有效的凭证");
    Code ACM_CUSTOMER_TENANT_OVERFLOW = new Code(463, "租户数量超出客户容许范围");
    Code ACM_TENANT_STATUS_MISMATCH = new Code(464, "租户状态不匹配");
    Code ACM_LICENSE_NO_AUTHORITY = new Code(465, "凭证没有授权");
    Code ACM_PERMISSION_PARENT_NOT_GRANTED = new Code(466, "上级权限未授权");

    Code ACM_SECURITY_LOGIN_INVALID = new Code(481, "登录已经失效");
    Code ACM_SECURITY_LOGIN_FAIL_MORE = new Code(482, "多次登录失败");
    Code ACM_SECURITY_LOGIN_FAIL_LIMIT = new Code(483, "登录失败次数达到上限");
    Code ACM_SECURITY_LOGOFF_DUPLICATE = new Code(484, "用户当前正在退出中");
    Code ACM_SECURITY_LOGIN_DUPLICATE = new Code(485, "用户当前正在登录中");
    Code ACM_SECURITY_TOKEN_NOT_ONLINE = new Code(486, "用户令牌不在线");
    Code ACM_SECURITY_TOKEN_NOT_EXIST = new Code(487, "登录令牌不存在");
    Code ACM_SECURITY_TOKEN_KICKOFF = new Code(488, "登录被踢出");
    Code ACM_SECURITY_SECRET_INVALID_CIPHER = new Code(489, "无效的密文");
    Code ACM_SECURITY_TOKEN_FORMAT = new Code(490, "令牌格式错误");
    Code ACM_SECURITY_ACCOUNT_EXPIRED = new Code(491, "账号已经过期");
    Code ACM_SECURITY_ACCOUNT_DISABLED = new Code(492, "账号被禁用");
    Code ACM_APP_STAMP_OVER_THRESHOLD = new Code(493, "时间戳超出了有效时间范围");
    Code ACM_APP_ALREADY_DISABLED = new Code(494, "接入应用已经停用");
    Code ACM_TOKEN_ISSUER = new Code(495, "令牌发行商不一致");
    Code ACM_TOKEN_SIGNATURE = new Code(496, "令牌签名错误");
    Code ACM_TOKEN_EXPIRED = new Code(497, "登录过期");
    Code ACM_ACCOUNT_LOCKED = new Code(498, "账号被锁定");

    Code SYS_INTERNAL_ERROR = new Code(500, "系统内部错误");
    Code SYS_SERVICE_UNSUPPORTED = new Code(501, "不支持的服务");
    Code SYS_SERVICE_UNAVAILABLE = new Code(503, "服务不可用");

    Code BIZ_FOREIGNER_PARENT_NOT_EXIST = new Code(602, "所属上级不存在");
    Code BIZ_ASSOCIATION_NOT_EXIST = new Code(603, "关系对象不存在");
    Code BIZ_ASSOCIATION_MISMATCH = new Code(604, "关系对象不匹配");
    Code BIZ_DOMAIN_ILLEGAL = new Code(605, "非法的对象记录");
    Code BIZ_DOMAIN_REFERENCED = new Code(606, "对象被引用");

    static Code from(int error){
        Field[] fields = Errors.class.getFields();
        for(Field field : fields){
            if (Code.class.equals(field.getType())){
                try {
                    Code code = (Code)field.get(Errors.class);
                    if (code.getError() == error){
                        return code;
                    }
                }catch (Exception e){
                    // do nothing
                }
            }
        }
        return Code.from(error);
    }
}
